#ifndef DIJKSTRA_H_
#define DIJKSTRA_H_
#include <functional>
#include <queue>
#include <vector>

#include "algorithm.h"
#include "graph.h"

class dijkstra : public Algorithm{
public:
    dijkstra() {}
    ~dijkstra();
    void SetupTopology(Graph* graph) override;
    Path FindPath(const Flow& flow) override;
    void Check();
    void GetInterationsNum(){
        std::cout<<num_iterations_;
    };

private:
    std::vector<std::vector<Lable>> L_perm; // permanent labels
    std::vector<std::vector<Lable>> L_clear;
    struct cmp{
        bool operator() (const Lable& l1, const Lable& l2){
            return l1.weight> l2.weight;
        }
    } ;// 小堆顶
    std::vector<std::priority_queue<Lable, std::vector<Lable>, cmp>> Q_tent;//tentative labels
    std::vector<std::priority_queue<Lable, std::vector<Lable>, cmp>> Q_clear;
    std::vector<bool> Visited; // 记录是否已经访问过

 private:


    // Helper functions
    std::vector<int> Intersection(std::vector<int> v1, std::vector<int> v2);
    bool Judge(std::vector<int> v1,std::vector<int> v2);

    void Relax_delay(Link* e, Lable l);
    bool Lable_Judge(Lable& l1, Lable& l2);

    void Dijkstra_method(NodeId begin, NodeId end);
    Path Trace_back(NodeId begin, NodeId end);

    // Variables for dijskra
    bool* visited_;
    Flow flow_;
    int tmp_min_delay;
    int num_nodes_;
    int num_iterations_;
};
#endif //DIJSKRA_H_